package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/louloulin/dataflare/pkg/actor/lifecycle"
)

// MyActor 是一个自定义Actor
type MyActor struct {
	lifecycle.LifecycleAwareActor
	data string
}

// NewMyActor 创建一个新的MyActor
func NewMyActor(id string, data string) *MyActor {
	actor := &MyActor{
		data: data,
	}
	actor.Initialize(id)
	return actor
}

// OnInit 初始化Actor
func (a *MyActor) OnInit() error {
	err := a.LifecycleAwareActor.OnInit()
	if err != nil {
		return err
	}
	fmt.Printf("Actor %s initialized with data: %s\n", a.Metrics.ID, a.data)
	return nil
}

// OnStart 启动Actor
func (a *MyActor) OnStart() error {
	err := a.LifecycleAwareActor.OnStart()
	if err != nil {
		return err
	}
	fmt.Printf("Actor %s started\n", a.Metrics.ID)
	return nil
}

// OnStop 停止Actor
func (a *MyActor) OnStop() error {
	err := a.LifecycleAwareActor.OnStop()
	if err != nil {
		return err
	}
	fmt.Printf("Actor %s stopped\n", a.Metrics.ID)
	return nil
}

// Process 处理消息
func (a *MyActor) Process(message string) {
	a.RecordMessageReceived()
	fmt.Printf("Actor %s processing message: %s\n", a.Metrics.ID, message)
	a.RecordMessageSent()
}

func main() {
	// 创建监督策略
	strategy := lifecycle.NewOneForOneStrategy(3, 10*time.Second, 1.0, 5*time.Second)

	// 创建监督者
	supervisor := lifecycle.NewSupervisor(strategy)

	// 创建Actor
	actor1 := NewMyActor("actor-1", "Hello, World!")
	actor2 := NewMyActor("actor-2", "Hello, DataFlare!")

	// 初始化Actor
	err := actor1.OnInit()
	if err != nil {
		log.Fatalf("Failed to initialize actor1: %v", err)
	}
	err = actor2.OnInit()
	if err != nil {
		log.Fatalf("Failed to initialize actor2: %v", err)
	}

	// 添加Actor到监督者
	supervisor.AddChild(&actor1.LifecycleAwareActor)
	supervisor.AddChild(&actor2.LifecycleAwareActor)

	// 启动Actor
	err = actor1.OnStart()
	if err != nil {
		log.Fatalf("Failed to start actor1: %v", err)
	}
	err = actor2.OnStart()
	if err != nil {
		log.Fatalf("Failed to start actor2: %v", err)
	}

	// 处理消息
	actor1.Process("Message 1")
	actor2.Process("Message 2")

	// 创建远程Actor系统
	transport := &MockTransport{}
	remoteSystem := lifecycle.NewRemoteActorSystem("node-1", "localhost:8080", transport)
	err = remoteSystem.Start()
	if err != nil {
		log.Fatalf("Failed to start remote system: %v", err)
	}

	// 创建远程Actor
	remoteActor := lifecycle.NewRemoteLifecycleAwareActor("remote-actor", remoteSystem)
	err = remoteActor.OnStart()
	if err != nil {
		log.Fatalf("Failed to start remote actor: %v", err)
	}

	// 发送远程消息
	err = remoteActor.SendRemote(context.Background(), "receiver", "test-message", []byte("Hello, Remote!"), map[string]string{"key": "value"})
	if err != nil {
		log.Fatalf("Failed to send remote message: %v", err)
	}

	// 打印Actor指标
	fmt.Println("\nActor Metrics:")
	fmt.Printf("Actor 1: %s\n", actor1)
	fmt.Printf("Actor 2: %s\n", actor2)
	fmt.Printf("Remote Actor: %s\n", remoteActor)

	// 停止Actor
	err = actor1.OnStop()
	if err != nil {
		log.Fatalf("Failed to stop actor1: %v", err)
	}
	err = actor2.OnStop()
	if err != nil {
		log.Fatalf("Failed to stop actor2: %v", err)
	}
	err = remoteActor.OnStop()
	if err != nil {
		log.Fatalf("Failed to stop remote actor: %v", err)
	}

	// 停止远程系统
	err = remoteSystem.Stop()
	if err != nil {
		log.Fatalf("Failed to stop remote system: %v", err)
	}
}

// MockTransport 是一个模拟的远程传输
type MockTransport struct {
	messages []*lifecycle.RemoteMessage
}

func (t *MockTransport) Send(ctx context.Context, message *lifecycle.RemoteMessage) error {
	t.messages = append(t.messages, message)
	fmt.Printf("Sent remote message: %s -> %s (%s)\n", message.SenderID, message.ReceiverID, message.MessageType)
	return nil
}

func (t *MockTransport) Receive(ctx context.Context) (*lifecycle.RemoteMessage, error) {
	if len(t.messages) == 0 {
		return nil, fmt.Errorf("no messages")
	}
	message := t.messages[0]
	t.messages = t.messages[1:]
	return message, nil
}

func (t *MockTransport) Start(ctx context.Context) error {
	fmt.Println("Mock transport started")
	return nil
}

func (t *MockTransport) Stop(ctx context.Context) error {
	fmt.Println("Mock transport stopped")
	return nil
}
